home *** CD-ROM | disk | FTP | other *** search
/ The Best of Down Under Games / The Best of Down Under Games.iso / 3dfx Screen Savers / Power Render / SRC.ZIP / SAVER.C < prev    next >
C/C++ Source or Header  |  1997-07-10  |  30KB  |  1,047 lines

  1. #include <math.h>
  2. #include <malloc.h>
  3. #include <stdlib.h>
  4. #include <direct.h>
  5. #include <string.h>
  6. #include <conio.h>
  7.  
  8. #include <pr.h>
  9. #include <prsound.h>
  10.  
  11. /* Egerter Software 3Dfx ScreenSaver
  12.    Copyright 1997 Egerter Software
  13.  
  14.    Written by Chris Egerter, July 1997
  15.  
  16.    Requirements:
  17.      Pentium microprocessor
  18.      3Dfx compatible card
  19.      DirectX for DirectInput and DirectSound (Windows version only)
  20.    
  21.  
  22.    To compile this, you need:
  23.  
  24.      DOS version:
  25.        Power Render 2.31, WGT 5.1, SEAL 1.03, Watcom C/C++
  26.  
  27.      Win32 version:
  28.        Power Render 2.31, SEAL 1.03, Watcom C/C++ or MSVC
  29.  
  30.    Free versions of Power Render, WGT, and SEAL are available from
  31.    http://www.egerter.com, but you'll have to buy a compiler :)
  32.  
  33.  
  34.    Other notes:
  35.      If you experience stuttering sound under Windows, make sure your sound
  36.      driver is DirectSound compatible and you have the latest drivers.
  37.      If that doesn't work, turn off the sound! :)
  38.      
  39. */
  40.  
  41.  
  42.  
  43. #if defined (MSGLIDE) || defined (WTGLIDE)
  44.  #include <glide.h>
  45.  #include <pr3dfx.h>
  46.  #include "winutil.h"
  47. #else
  48.  #ifdef __3DFX__
  49.   #include <pr3dfx.h>
  50.   #include <glide.h>
  51.  #endif
  52. #endif
  53.  
  54. #include <prgui.h>
  55.  
  56. /* Switches */
  57. PR_DWORD nomusic = 0;
  58. PR_DWORD nowav = 0;
  59. PR_DWORD nosound = 0;
  60.  
  61.  
  62. /* ---------------------------------------------------------------------
  63.    Devices and Viewports
  64.    --------------------------------------------------------------------- */
  65. PR_DWORD     device;
  66. PR_DWORD     current_mode;          /* Current video mode */
  67. PR_DWORD     vwidth;                /* Viewport size */
  68. PR_DWORD     vheight;
  69. PR_VIEWPORT  viewport;              /* Our viewport structure */
  70.  
  71.  
  72. /* ---------------------------------------------------------------------
  73.    Lights and Cameras
  74.    --------------------------------------------------------------------- */
  75. PR_CAMERA *  camera;                /* One camera */
  76. PR_LIGHTLIST JetLights;             /* We only use 1 light that follows
  77.                                        the camera */
  78. PR_LIGHTLIST HeadLights;             
  79. PR_LIGHTLIST BumpLights;             
  80.                                      
  81.  
  82. /* ---------------------------------------------------------------------
  83.    Sound Effects and Music
  84.    --------------------------------------------------------------------- */
  85. PR_DWORD WAVrocket;
  86. PR_DWORD WAVrocket2;
  87. PR_DWORD WAVambient;
  88. PR_3DSOUND *rocket;
  89. PR_3DSOUND *rocket2;
  90. PR_3DSOUND *ambient;
  91.  
  92.  
  93. /* ---------------------------------------------------------------------
  94.    Objects and Entities
  95.    --------------------------------------------------------------------- */
  96. /* Scene 1 */
  97. PR_OBJECT *jet_object;
  98. PR_ENTITY *jet_arena;
  99. PR_ENTITY *dummy_ent;           /* Dummy entity used for 3D sound */
  100. PR_ENTITY *dummy_ent2;          /* Dummy entity used for 3D sound */
  101. PR_ENTITY *dummy_ent3;          /* Dummy entity used for 3D sound */
  102.  
  103. /* Scene 2 */
  104. PR_OBJECT *bump_object;         /* Room definition */
  105. PR_ENTITY *bump_room;
  106. PR_OBJECT *campathobj;          
  107. PR_ENTITY *campath;             /* Camera path entity */
  108.  
  109. /* Scene 3 */
  110. PR_OBJECT *logo_object;         /* Room definition */
  111. PR_ENTITY *logo_room;
  112.  
  113.  
  114. /* ---------------------------------------------------------------------
  115.    Bump Map Stuff 
  116.    --------------------------------------------------------------------- */
  117. void UpdateBump (void);
  118. void InitializeBump (void);
  119. void CalcLightSource (unsigned char *light);
  120. void BumpLight (unsigned char *dest, PR_DWORD lx, PR_DWORD ly,
  121.                 unsigned char *light, PR_DWORD half);
  122.  
  123. extern GrMipMapId_t *PR_TextureHandles;
  124. PR_DWORD bumpmap;
  125. #define XLIGHT 256
  126. #define YLIGHT 256
  127. #define XMLIGHT 255
  128. #define YMLIGHT 255
  129. #define XHLIGHT 127
  130. #define YHLIGHT 127
  131. PR_DWORD bumphalf = 1;
  132. block bump_dest;
  133. unsigned char *bumpx;
  134. unsigned char *bumpy;
  135. unsigned char *lightsource;
  136. color bumppal[256];
  137. PR_REAL bump_angle = 0, bump_angle2 = 0;
  138.  
  139.  
  140. /* ---------------------------------------------------------------------
  141.    Frame Rate Control  
  142.    --------------------------------------------------------------------- */
  143. PR_DWORD ticks;                 /* Total number of ticks passed */
  144. PR_DWORD updates;               /* Total number of updates */
  145. PR_DWORD framerate;             /* Resulting frame rate (updates/ticks/tickrate) */
  146. PR_DWORD show_frame_rate = 0;
  147.  
  148. PR_DWORD sky_color;
  149. PR_DWORD quit_saver = 0;
  150. PR_DWORD frame = 0;
  151. PR_DWORD pathframe = 0;
  152.  
  153.  
  154. /* ---------------------------------------------------------------------
  155.    Only 3Dfx is supported
  156.    --------------------------------------------------------------------- */
  157. void InitializeDevices (void)
  158. {
  159.   device = PR_Detect3Dfx ();
  160.   PR_Initialize3Dfx ();
  161.   atexit (PR_Shutdown3Dfx);
  162.  
  163.  
  164.   /* And allocate room for data */
  165.   PR_AllocMaterials (128);
  166.   PR_AllocTextures (64);
  167.   PR_AllocShadeTables (16);
  168. }
  169.  
  170.  
  171. /* ---------------------------------------------------------------------
  172.    Load the song and wav files
  173.    --------------------------------------------------------------------- */
  174. void InitializeAudio (void)
  175. {
  176.   /* initialize audio library */
  177.   PRSND_Initialize ();
  178.   PRSND_AllocSounds (3);
  179.  
  180.   /* open audio device */
  181.   PRSND_OpenAudio (AUDIO_DEVICE_MAPPER,
  182.                    AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO,
  183.                    22050);
  184.  
  185.   if (!nomusic)
  186.     PRSND_LoadSong ("saver.s3m");
  187.  
  188.   PRSND_InitializeVoices (3);
  189.  
  190.   if (!nomusic)
  191.     {
  192.      PRSND_PlaySong ();
  193.      PRSND_SetSongVolume (52);
  194.     }
  195.  
  196.   /* load module and waveform file */
  197.   if (!nowav)
  198.     {
  199.      WAVrocket = PRSND_LoadSound ("ship.wav");
  200.      WAVrocket2 = PRSND_LoadSound ("ship2.wav");
  201.      WAVambient = PRSND_LoadSound ("wind.wav");
  202.  
  203.      PRSND_SetLoopStart (WAVrocket, 0);
  204.      PRSND_SetLoopEnd (WAVrocket, PRSND_GetLength (WAVrocket));
  205.      PRSND_SetLoopMode (WAVrocket, 1);
  206.  
  207.      PRSND_SetLoopStart (WAVrocket2, 0);
  208.      PRSND_SetLoopEnd (WAVrocket2, PRSND_GetLength (WAVrocket2));
  209.      PRSND_SetLoopMode (WAVrocket2, 1);
  210.  
  211.      PRSND_SetLoopStart (WAVambient, 0);
  212.      PRSND_SetLoopEnd (WAVambient, PRSND_GetLength (WAVambient));
  213.      PRSND_SetLoopMode (WAVambient, 1);
  214.  
  215.      rocket = PRSND_Alloc3DSound ();
  216.      rocket2 = PRSND_Alloc3DSound ();
  217.      ambient = PRSND_Alloc3DSound ();
  218.     }
  219. }
  220.  
  221.  
  222. /* ---------------------------------------------------------------------
  223.    Set up the 3D sounds
  224.    --------------------------------------------------------------------- */
  225. void InitializeWAV (void)
  226. {
  227.   /* play the waveform through a voice */
  228.   if (!nowav)
  229.     {
  230.      PRSND_Play3DSound (rocket, WAVrocket);
  231.      PRSND_Set3DSoundVolume (rocket, 64);
  232.      PRSND_Set3DSoundVolumeMode (rocket, SOUND_3D_VOLUME);
  233.      PRSND_Set3DSoundVolumeFactor (rocket, 5000);
  234.      PRSND_Set3DSoundPanning (rocket, 128);
  235.      PRSND_Set3DSoundPanningMode (rocket, SOUND_3D_PANNING);
  236.      PRSND_Set3DSoundPanningFactor (rocket, 1000);
  237.      PRSND_Set3DSoundShiftMode (rocket, SOUND_DOPPLER_ON);
  238.      PRSND_Set3DSoundShiftFactor (rocket, 0.005);
  239.      PRSND_Set3DSoundShiftSlide (rocket, 50);
  240.      PRSND_Set3DSoundCoordinate (rocket, 0, 0, 0, dummy_ent);
  241.      PRSND_Update3DSound (rocket);
  242.  
  243.      /* play the waveform through a voice */
  244.      PRSND_Play3DSound (rocket2, WAVrocket2);
  245.      PRSND_Set3DSoundVolume (rocket2, 64);
  246.      PRSND_Set3DSoundVolumeMode (rocket2, SOUND_3D_VOLUME);
  247.      PRSND_Set3DSoundVolumeFactor (rocket2, 5000);
  248.      PRSND_Set3DSoundPanning (rocket2, 128);
  249.      PRSND_Set3DSoundPanningMode (rocket2, SOUND_3D_PANNING);
  250.      PRSND_Set3DSoundPanningFactor (rocket2, 1000);
  251.      PRSND_Set3DSoundShiftMode (rocket2, SOUND_DOPPLER_ON);
  252.      PRSND_Set3DSoundShiftFactor (rocket2, 0.005);
  253.      PRSND_Set3DSoundShiftSlide (rocket2, 50);
  254.      PRSND_Set3DSoundCoordinate (rocket2, 0, 0, 0, dummy_ent2);
  255.      PRSND_Update3DSound (rocket2);
  256.  
  257.      /* play the waveform through a voice */
  258.      PRSND_Play3DSound (ambient, WAVambient);
  259.      PRSND_Set3DSoundVolume (ambient, 64);
  260.      PRSND_Set3DSoundVolumeMode (ambient, SOUND_3D_VOLUME);
  261.      PRSND_Set3DSoundVolumeFactor (ambient, 5000);
  262.      PRSND_Set3DSoundPanning (ambient, 128);
  263.      PRSND_Set3DSoundPanningMode (ambient, SOUND_3D_PANNING);
  264.      PRSND_Set3DSoundPanningFactor (ambient, 1000);
  265.      PRSND_Set3DSoundShiftMode (ambient, SOUND_DOPPLER_ON);
  266.      PRSND_Set3DSoundShiftFactor (ambient, 0.005);
  267.      PRSND_Set3DSoundShiftSlide (ambient, 50);
  268.      PRSND_Set3DSoundCoordinate (ambient, 0, 0, 0, dummy_ent3);
  269.      PRSND_Update3DSound (ambient);
  270.  
  271.      PRSND_UpdateVoices ();
  272.     }
  273. }
  274.  
  275. /* ---------------------------------------------------------------------
  276.    Turn off and free the 3D sounds
  277.    --------------------------------------------------------------------- */
  278. void FreeWAV (void)
  279. {
  280.   if (!nowav)
  281.     {
  282.      /* Ask for a stop request */
  283.      PRSND_3DSoundList[ambient->soundnum]->active = SOUND_STOP_PLAYING;
  284.      PRSND_3DSoundList[rocket->soundnum]->active  = SOUND_STOP_PLAYING;
  285.      PRSND_3DSoundList[rocket2->soundnum]->active = SOUND_STOP_PLAYING;
  286.  
  287.      /* Process the requests */
  288.      PRSND_UpdateVoices ();
  289.     }
  290. }
  291.  
  292.  
  293. /* ---------------------------------------------------------------------
  294.    Initialize the video mode to 640x480
  295.    --------------------------------------------------------------------- */
  296. void InitializeVideo (void)
  297. {
  298.   vwidth = 640;
  299.   vheight = 480;
  300.   PR_SetMode (vwidth, vheight, 60);
  301.  
  302.   PR_OpenViewport (&viewport, 0, 0, vwidth-1, vheight-1, VIEW_PLAIN);
  303.  
  304.   PR_SetViewport (&viewport);
  305.   PRGFX_Clip (active_viewport.topx,
  306.               active_viewport.topy,
  307.               active_viewport.bottomx,
  308.               active_viewport.bottomy);
  309. }
  310.  
  311.  
  312. /* ---------------------------------------------------------------------
  313.    Make one light which will follow the camera 
  314.    --------------------------------------------------------------------- */
  315. void InitializeJetLights (void)
  316. {
  317.   /* Initialize the lights */
  318.   PR_AllocLights (&JetLights, 1);       /* Jet scene light */
  319.  
  320.   PR_SetLightOn (&JetLights, 0);
  321.   PR_SetLightType (&JetLights, 0, DIRECTIONAL_LIGHT);
  322.   PR_SetLightStrength (&JetLights, 0, 1.0);
  323.   PR_SetLightColor (&JetLights, 0, 1.0, 1.0, 1.0);
  324.   /* Position doesn't matter because we set it to the camera location every frame */
  325.  
  326.   JetLights.NumLights = 1;     /* This sets how many lights are actually used */
  327. }
  328.  
  329.  
  330. /* ---------------------------------------------------------------------
  331.    Initialize Bump lights (3 colored ones)
  332.    --------------------------------------------------------------------- */
  333. void InitializeBumpLights (void)
  334. {
  335.   PR_AllocLights (&BumpLights, 3);
  336.   PR_SetLightPosition (&BumpLights, 0, 0, 0, 400);
  337.   PR_SetLightOn (&BumpLights, 0);
  338.   PR_SetLightType (&BumpLights, 0, DIRECTIONAL_LIGHT);
  339.   PR_SetLightColor (&BumpLights, 0, 1.0, 1.0, 1.0);
  340.   PR_SetLightStrength (&BumpLights, 0, 1.0);
  341.  
  342.   PR_SetLightPosition (&BumpLights, 1, 0, 500, 400);
  343.   PR_SetLightOn (&BumpLights, 1);
  344.   PR_SetLightType (&BumpLights, 1, DIRECTIONAL_LIGHT);
  345.   PR_SetLightColor (&BumpLights, 1, 0.0, 0.0, 1.0);
  346.   PR_SetLightStrength (&BumpLights, 1, 1.0);
  347.  
  348.   PR_SetLightPosition (&BumpLights, 2, -500, 200, 400);
  349.   PR_SetLightOn (&BumpLights, 2);
  350.   PR_SetLightType (&BumpLights, 2, DIRECTIONAL_LIGHT);
  351.   PR_SetLightColor (&BumpLights, 2, 0.0, 1.0, 0.0);
  352.   PR_SetLightStrength (&BumpLights, 2, 1.0);
  353.   BumpLights.NumLights = 3;     /* This sets how many lights are actually used */
  354. }
  355.  
  356. /* ---------------------------------------------------------------------
  357.    Loads the jet scene and makes dummy entities for 3D sounds
  358.    --------------------------------------------------------------------- */
  359. void LoadJetScene (void)
  360. {
  361. PR_ENTITY *dum;
  362.  
  363.   /* Preload some textures with different formats */
  364.   PR_SetTextureFormat (TEXTURE_RGB_332);
  365.   PR_LoadTexture ("green.pcx");
  366.   PR_LoadTexture ("purpmet.pcx");
  367.   PR_LoadTexture ("metal.pcx");
  368.   PR_SetTextureFormat (TEXTURE_XRAY);
  369.   PR_LoadTexture ("tower.pcx");
  370.   PR_SetTextureFormat (TEXTURE_RGB_565);
  371.  
  372.   jet_object = PR_LoadPRO ("jet.pro", LOAD_NORMAL);
  373.   jet_object->segment_list[48].num_faces = 0;  /* prevent rendering the dummy object */
  374.   jet_arena = PR_CreateEntity (jet_object, "Jet Arena");
  375.   PR_ScaleEntityAbs (jet_arena, 1, 1, 1);
  376.  
  377.   /* The following are dummy entities that have 3D sounds attached to
  378.      them.  This is necessary because the 3D sounds must be
  379.      associated with an entity instead of a segment. */
  380.  
  381.   dum = jet_arena;
  382.   dummy_ent = PR_CreateEntity (jet_object, "dummy");
  383.   PR_PositionEntity (dummy_ent, dum->segment_orientation[45].location.x,
  384.                                 dum->segment_orientation[45].location.y,
  385.                                 dum->segment_orientation[45].location.z);
  386.  
  387.   dummy_ent2 = PR_CreateEntity (jet_object, "dummy2");
  388.   PR_PositionEntity (dummy_ent2, dum->segment_orientation[47].location.x,
  389.                                  dum->segment_orientation[47].location.y,
  390.                                  dum->segment_orientation[47].location.z);
  391.  
  392.   dummy_ent3 = PR_CreateEntity (jet_object, "dummy3");
  393.   PR_PositionEntity (dummy_ent3, dum->segment_orientation[8].location.x,
  394.                                  dum->segment_orientation[8].location.y,
  395.                                  dum->segment_orientation[8].location.z);
  396.   InitializeJetLights ();
  397. }
  398.  
  399.  
  400. /* ---------------------------------------------------------------------
  401.    Loads the bump mapped scene 
  402.    --------------------------------------------------------------------- */
  403. void LoadBumpScene (void)
  404. {
  405.   InitializeBump ();
  406.  
  407.   bump_object = PR_LoadPRO ("head.pro", LOAD_NORMAL);
  408.   bump_room = PR_CreateEntity (bump_object, "Bump Room");
  409.   PR_ScaleEntityAbs (bump_room, 1, 1, 1);
  410.  
  411.   campathobj = PR_LoadPRO ("headpath.pro", LOAD_NORMAL);
  412.   campath = PR_CreateEntity (campathobj, "Path");
  413.   PR_ScaleEntityAbs (campath, 1, 1, 1);
  414.  
  415.   InitializeBumpLights ();
  416. }
  417.  
  418.  
  419. /* ---------------------------------------------------------------------
  420.    Loads the 3Dfx logo scene 
  421.    --------------------------------------------------------------------- */
  422. void LoadLogoScene (void)
  423. {
  424.   logo_object = PR_LoadPRO ("3dlogo.pro", LOAD_NORMAL);
  425.   logo_room = PR_CreateEntity (logo_object, "Logo Room");
  426.   PR_ScaleEntityAbs (logo_room, 1, 1, 1);
  427.   PR_SetTextureFormat (TEXTURE_NORMAL);
  428. }
  429.  
  430.  
  431.  
  432. /* ---------------------------------------------------------------------
  433.    Timer Interrupt 
  434.    --------------------------------------------------------------------- */
  435. void timerproc (void)
  436. {
  437.   ticks++;
  438.   AUpdateAudio ();
  439. }                
  440.  
  441.  
  442. /* ---------------------------------------------------------------------
  443.    Get user input
  444.    --------------------------------------------------------------------- */
  445. void UserInput (void)
  446. {
  447. PR_DWORD dummy = 0;
  448.  
  449.   /* Keyboard input */
  450.  
  451.   if (kbdon[KEY_F1])            /* Pause */
  452.     {
  453.      APauseModule ();           /* SEAL commands */
  454.  
  455.      while (kbdon[KEY_F1])     
  456.        { 
  457.         dummy++;
  458.         #ifdef WIN32
  459.           UpdateMessages ();
  460.         #endif
  461.        }           /* Wait for user to release key */
  462.  
  463.  
  464.      while (!kbdon[KEY_F1])     
  465.        { 
  466.         dummy++;
  467.         #ifdef WIN32
  468.           UpdateMessages ();
  469.         #endif
  470.        }           /* Wait for user to hit key */
  471.  
  472.      AResumeModule ();
  473.     }
  474.  
  475. }
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484. /* ---------------------------------------------------------------------
  485.    Calculates the light source map
  486.    --------------------------------------------------------------------- */
  487. void CalcLightSource (unsigned char *light)
  488. {
  489. PR_DWORD i,j;
  490. PR_REAL  dist, tx, ty;
  491.  
  492.   for (i = 0; i < XLIGHT; i++)
  493.     for (j = 0; j < YLIGHT; j++)
  494.     {
  495.       tx = i - XHLIGHT;
  496.       ty = j - YHLIGHT;
  497.       dist = sqrt(tx*tx + ty*ty);
  498.       if (dist < 160)
  499.         light[i*XLIGHT+j] = (63 - (dist*0.4)) + 1;
  500.       else
  501.         light[i*XLIGHT+j] = 1;
  502.       if (light[i*XLIGHT+j] < 1)
  503.         light[i*XLIGHT+j] = 1;
  504.     }
  505. }
  506.  
  507.  
  508.  
  509. /* ---------------------------------------------------------------------
  510.    Precalculates the x and y offsets
  511.    --------------------------------------------------------------------- */
  512. void PrecalcBump (unsigned char *bump)
  513. {
  514. PR_DWORD x, y;
  515. PR_DWORD middle;
  516. PR_DWORD top;
  517. PR_DWORD bottom;
  518. PR_DWORD left;
  519. PR_DWORD right;
  520. PR_DWORD dx, dy;
  521.  
  522.   memset (bumpx, 0, 256*256);
  523.   memset (bumpy, 0, 256*256);
  524.  
  525.   for (x = 1; x < 255; x++)
  526.    for (y = 1; y < 255; y++)
  527.      {
  528.  
  529.       middle = bump[y*256 + x];
  530.       left   = ((int)bump[y*256 + x - 1] - middle);
  531.       right  = ((int)bump[y*256 + x + 1] - middle);
  532.       top    = ((int)bump[y*256 + x - 256] - middle);
  533.       bottom = ((int)bump[y*256 + x + 256] - middle);
  534.       dx  = (left - right) >> 1;
  535.       dy  = (top - bottom) >> 1;
  536.  
  537.       bumpx[y*256 + x] = dx;
  538.       bumpy[y*256 + x] = dy;
  539.      }
  540. }
  541.  
  542.  
  543.  
  544. /* ---------------------------------------------------------------------
  545.    Draw the bump bitmap
  546.    --------------------------------------------------------------------- */
  547. void BumpLight (unsigned char *dest, PR_DWORD lx, PR_DWORD ly,
  548.                 unsigned char *light, PR_DWORD half)
  549. {
  550. unsigned char *blutx, *bluty;
  551.  
  552. int lx1, ly1, lx2, ly2;
  553. int dx, dy;
  554. int sofs;
  555. int slx, sly, x, y;
  556. int tlx, tly;
  557.  
  558.   lx1 = lx - 127;
  559.   ly1 = ly - 127;
  560.   lx2 = lx + 127;
  561.   ly2 = ly + 127;
  562.   slx = lx1;
  563.   sly = ly1;
  564.   if (lx1 < 1)   { slx = lx1; lx1 = 1; }
  565.   if (lx1 > 254) return;
  566.   if (ly1 < 1)   { sly = ly1; ly1 = 1; }
  567.   if (ly1 > 254) return;
  568.  
  569.   lx1 = 0;
  570.   lx2 = 256;
  571.  
  572.   if (half)
  573.     {
  574.      ly1 = 128;
  575.      ly2 = 256;
  576.     }
  577.   else
  578.     {
  579.      ly1 = 0;
  580.      ly2 = 128;
  581.     }
  582.  
  583.  
  584.   if (lx2 > 254) lx2 = 254;
  585.   if (lx2 < 1)   return;
  586.   if (ly2 > 254) ly2 = 254;
  587.   if (ly2 < 1)   return;
  588.  
  589.   y = ly1;
  590.   sofs = ly1 * 256;
  591.  
  592.   while (y < ly2)
  593.   {
  594.     x = lx1;
  595.     sofs += lx1;
  596.     tlx = x - slx;
  597.     tly = y - sly;
  598.  
  599.     blutx = &bumpx[sofs];
  600.     bluty = &bumpy[sofs];
  601.  
  602.     while (x++ < lx2)
  603.     {
  604.       dx = *(blutx++);
  605.       dy = *(bluty++);
  606.  
  607.       *(dest + sofs++) =
  608.          light[(((tly+dy) & YMLIGHT) << 8)+(((tlx++)+dx) & XMLIGHT)];
  609.     }
  610.     tly++;
  611.     sofs += (256-lx2);
  612.     y++;
  613.   }
  614. }
  615.  
  616.  
  617. /* ---------------------------------------------------------------------
  618.    Initialize the Bump data
  619.    --------------------------------------------------------------------- */
  620. void InitializeBump (void)
  621. {
  622.   lightsource = malloc (XLIGHT*YLIGHT);
  623.   bumpx = malloc (256 * 256);
  624.   bumpy = malloc (256 * 256);
  625.  
  626.   PR_Settings.LoadPalette = 1;
  627.   PR_SetTextureFormat (TEXTURE_P_8);
  628.   bumpmap = PR_LoadTexture ("bumpmap.pcx");
  629.   PR_SetTextureFormat (TEXTURE_NORMAL);
  630.  
  631.   CalcLightSource (lightsource);
  632.   PrecalcBump (PR_WorldTextures[bumpmap].image + 4);
  633.   bump_angle = 0;
  634.   bump_angle2 = 0;
  635. }
  636.  
  637.  
  638.  
  639.  
  640. /* ---------------------------------------------------------------------
  641.    Moves the lightsource and draws the bump map
  642.    The image is drawn in 2 parts, so the texture is updated every other
  643.    frame.
  644.    --------------------------------------------------------------------- */
  645. void UpdateBump (void)
  646. {
  647. PR_REAL lightx, lightz;
  648. PR_DWORD x, y;
  649. GrMipMapId_t temptex;
  650.  
  651.   lightx = (sin(bump_angle + bump_angle2)*100);
  652.   lightz = (cos(2*bump_angle + sin(bump_angle2))*80);
  653.   x = 127 + lightx;
  654.   y = 127 + lightz;
  655.  
  656.   bumphalf = !bumphalf;
  657.   if (bumphalf)  /* Top half */
  658.     {
  659.      BumpLight (PR_WorldTextures[bumpmap].image + 4, x, y, lightsource, bumphalf);
  660.     }
  661.   else
  662.     {
  663.      BumpLight (PR_WorldTextures[bumpmap].image + 4, x, y, lightsource, bumphalf);
  664.  
  665.      memcpy (&temptex,  &PR_TextureHandles[bumpmap], sizeof (GrMipMapId_t));
  666.      guTexDownloadMipMap (temptex,
  667.                          (void *)(PR_WorldTextures[bumpmap].image + 4),
  668.                           NULL);
  669.  
  670.      bump_angle += 3.141592 / 256.0 * 3;
  671.      bump_angle2 += 0.01;
  672.     }
  673. }
  674.  
  675.  
  676.  
  677. /* ---------------------------------------------------------------------
  678.    --------------------------------------------------------------------- */
  679. void InitializePowerRender (void)
  680. {
  681.   PRGUI_SetUserPath ();
  682.   PRGUI_GoStartPath ();
  683.  
  684.   PR_Initialize (5);  /* Don't need to worry about number of polys with 3Dfx */
  685.  
  686.   InitializeDevices ();
  687.  
  688.   PR_AllocLights (&scenelights, 6);     /* Master scene light list */
  689.  
  690.   InitializeVideo ();
  691.  
  692.   PR_SetTextureFormat (TEXTURE_XRAY);
  693.   PR_Settings.HardwareMipmaps = MIPMAP_ALL_LEVELS;
  694.   PRGFX_SetTextBackground (PRGFX_MakeColor (0,0,0));
  695.   PRGFX_SetTextTransparent (TEXTFGBG);
  696.   sky_color = PRGFX_MakeColor (0, 0, 0);
  697.  
  698.   gui_font = NULL;
  699.   PRGFX_SetTextForeground (PRGFX_MakeColor (0,63,63));
  700.   PRGUI_printf (0, 0, "Egerter Software 3Dfx ScreenSaver");
  701.   PRGUI_printf (0, 10, "Version 1.0");
  702.   PRGFX_SetTextForeground (PRGFX_MakeColor (63,63,63));
  703.   PRGUI_printf (0, 30, "Initializing...");
  704.  
  705.  
  706.   /* Initialize the camera */
  707.   camera = PR_AllocCamera ();
  708.   PR_InitializeCamera (camera);
  709.   PR_SetCameraMode (camera, CAMFLAG_AIM_TARGET);
  710.  
  711.   /* Initialize the input devices */
  712.   installkbd ();
  713.   winittimer ();
  714.   wstarttimer (timerproc, TICKS(60));
  715. }
  716.  
  717.  
  718. void DisplayFrameRate (void)
  719. {
  720.   /* Calculate the frame rate */
  721.   if (ticks > 60)
  722.     {
  723.      framerate = updates;
  724.      ticks = 0;
  725.      updates = 0;
  726.     }
  727.   else
  728.     updates++; 
  729.  
  730.   if (show_frame_rate)
  731.     PRGUI_printf (10, 10, "%i", framerate);
  732. }
  733.  
  734.  
  735.  
  736. void JetLoop (void)
  737. {
  738. PR_DWORD animation_finished = 0;
  739.  
  740.   frame = 0;
  741.   camera->fov = (1.0 / 3.0) * 3.1415;
  742.  
  743.   while ((!kbdon[KEY_ESC]) && (!animation_finished))
  744.     {
  745.      #ifdef WIN32
  746.       UpdateMessages ();
  747.      #endif
  748.       
  749.      UserInput ();
  750.      PR_NewFrame ();                         /* Begin a new frame */
  751.  
  752.      PRGFX_SetColor (sky_color);
  753.      PR_OpenScreen (PR_BACKBUFFER);
  754.  
  755.      PRGFX_ClearScreen ();
  756.  
  757.      PR_PositionCameraSource (camera, jet_arena->segment_orientation[48].location.x,
  758.                                       jet_arena->segment_orientation[48].location.y,
  759.                                       jet_arena->segment_orientation[48].location.z);
  760.      PR_PositionCameraTarget (camera, jet_arena->segment_orientation[45].location.x,
  761.                                       jet_arena->segment_orientation[45].location.y,
  762.                                       jet_arena->segment_orientation[45].location.z);
  763.  
  764.      if (!nowav)
  765.        {
  766.         PRSND_SetOrigin (camera->source.x, camera->source.y, camera->source.z);
  767.         PR_PositionEntity (dummy_ent, jet_arena->segment_orientation[45].location.x,
  768.                                       jet_arena->segment_orientation[45].location.y,
  769.                                       jet_arena->segment_orientation[45].location.z);
  770.         PR_PositionEntity (dummy_ent2,jet_arena->segment_orientation[47].location.x,
  771.                                       jet_arena->segment_orientation[47].location.y,
  772.                                       jet_arena->segment_orientation[47].location.z);
  773.        }
  774.  
  775.      PR_SetLightPosition (&JetLights, 0,
  776.                           camera->source.x,
  777.                           camera->source.y,
  778.                           camera->source.z);
  779.      PR_AddLightsToScene (&JetLights);
  780.  
  781.      PR_SetActiveCamera (camera);
  782.  
  783.      if (!nowav)
  784.        {
  785.         PRSND_Update3DSound (rocket);
  786.         PRSND_Update3DSound (rocket2);
  787.         PRSND_Update3DSound (ambient);
  788.         PRSND_UpdateVoices ();
  789.        }
  790.  
  791.      PRGFX_Clip (active_viewport.topx,
  792.                  active_viewport.topy,
  793.                  active_viewport.bottomx,
  794.                  active_viewport.bottomy);
  795.  
  796.      if (jet_arena->shape->num_frames > 0)
  797.        {
  798.         frame++;
  799.         if (frame >= jet_arena->shape->num_frames-1)
  800.           animation_finished = 1;
  801.         PR_AnimateEntity (jet_arena, frame);
  802.        }
  803.  
  804.      PR_TransformEntity (jet_arena);
  805.      PR_RenderEntity (jet_arena);
  806.  
  807.      DisplayFrameRate ();
  808.  
  809.      PR_Flip (1);
  810.     }
  811.  
  812.   if (kbdon[KEY_ESC])
  813.     quit_saver = 1;
  814. }
  815.  
  816.  
  817. void BumpLoop (void)
  818. {
  819. PR_DWORD animation_finished = 0;
  820.  
  821.   frame = 0;
  822.   pathframe = 0;
  823.   camera->fov = (2.0 / 3.0) * 3.1415;
  824.  
  825.   UpdateBump ();        /* Draw the top of the bump image */
  826.   UpdateBump ();        /* Draw the bottom of the bump image and download the texture */
  827.  
  828.   while ((!kbdon[KEY_ESC]) && (!animation_finished))
  829.     {
  830.      #ifdef WIN32
  831.       UpdateMessages ();
  832.      #endif
  833.       
  834.      UserInput ();
  835.      PR_NewFrame ();                         /* Begin a new frame */
  836.  
  837.      UpdateBump ();
  838.  
  839.      PRGFX_SetColor (sky_color);
  840.      PR_OpenScreen (PR_BACKBUFFER);
  841.  
  842.      PRGFX_ClearScreen ();
  843.  
  844.      PR_PositionCameraSource (camera, campath->segment_orientation[0].location.x,
  845.                                       campath->segment_orientation[0].location.y,
  846.                                       campath->segment_orientation[0].location.z);
  847.      PR_PositionCameraTarget (camera, bump_room->segment_orientation[3].location.x,
  848.                                       bump_room->segment_orientation[3].location.y,
  849.                                       bump_room->segment_orientation[3].location.z);
  850.  
  851.      PR_SetLightPosition (&BumpLights, 0,
  852.                           camera->source.x,
  853.                           camera->source.y,
  854.                           camera->source.z);
  855.      PR_AddLightsToScene (&BumpLights);
  856.  
  857.      PR_SetActiveCamera (camera);
  858.  
  859.      PRGFX_Clip (active_viewport.topx,
  860.                  active_viewport.topy,
  861.                  active_viewport.bottomx,
  862.                  active_viewport.bottomy);
  863.  
  864.      frame++;
  865.      if (frame >= bump_room->shape->num_frames)
  866.        frame = 0;
  867.      PR_AnimateEntity (bump_room, frame);
  868.  
  869.      pathframe++;
  870.      if (pathframe >= campath->shape->num_frames)
  871.        {
  872.         animation_finished = 1;
  873.         pathframe = 0;
  874.        }
  875.      PR_AnimateEntity (campath, pathframe);
  876.  
  877.      PR_TransformEntity (bump_room);
  878.      PR_RenderEntity (bump_room);
  879.  
  880.      DisplayFrameRate ();
  881.  
  882.      PR_Flip (1);
  883.     }
  884.  
  885.   if (kbdon[KEY_ESC])
  886.     quit_saver = 1;
  887. }
  888.  
  889.  
  890. void LogoLoop (void)
  891. {
  892. PR_DWORD animation_finished = 0;
  893.  
  894.   frame = 0;
  895.   camera->fov = (1.8 / 3.0) * 3.1415;
  896.  
  897.   while ((!kbdon[KEY_ESC]) && (!animation_finished))
  898.     {
  899.      #ifdef WIN32
  900.       UpdateMessages ();
  901.      #endif
  902.       
  903.      UserInput ();
  904.      PR_NewFrame ();                         /* Begin a new frame */
  905.  
  906.      PRGFX_SetColor (sky_color);
  907.      PR_OpenScreen (PR_BACKBUFFER);
  908.  
  909.      PRGFX_ClearScreen ();
  910.  
  911.      PR_PositionCameraSource (camera, logo_room->segment_orientation[5].location.x,
  912.                                       logo_room->segment_orientation[5].location.y,
  913.                                       logo_room->segment_orientation[5].location.z);
  914.      PR_PositionCameraTarget (camera, logo_room->segment_orientation[8].location.x,
  915.                                       logo_room->segment_orientation[8].location.y,
  916.                                       logo_room->segment_orientation[8].location.z);
  917.  
  918.      PR_SetLightPosition (&JetLights, 0,
  919.                           camera->source.x,
  920.                           camera->source.y,
  921.                           camera->source.z);
  922.      PR_AddLightsToScene (&JetLights);
  923.  
  924.      PR_SetActiveCamera (camera);
  925.  
  926.      PRGFX_Clip (active_viewport.topx,
  927.                  active_viewport.topy,
  928.                  active_viewport.bottomx,
  929.                  active_viewport.bottomy);
  930.  
  931.      if (logo_room->shape->num_frames > 0)
  932.        {
  933.         frame++;
  934.         if (frame >= logo_room->shape->num_frames-1)
  935.           animation_finished = 1;
  936.         PR_AnimateEntity (logo_room, frame);
  937.        }
  938.  
  939.      PR_TransformEntity (logo_room);
  940.      PR_RenderEntity (logo_room);
  941.  
  942.      DisplayFrameRate ();
  943.  
  944.      PR_Flip (1);
  945.     }
  946.  
  947.   if (kbdon[KEY_ESC])
  948.     quit_saver = 1;
  949. }
  950.  
  951.  
  952.  
  953.  
  954.  
  955. /* ---------------------------------------------------------------------- */
  956. /* Main program */
  957. /* ---------------------------------------------------------------------- */
  958. void main (int argc, char *argv[])
  959. {
  960. PR_DWORD argnum;
  961.  
  962.   argnum = 1;
  963.   while (argnum < argc)
  964.     {
  965.      if (!strcmp (argv[argnum], "-nomusic"))
  966.        nomusic = 1;
  967.      if (!strcmp (argv[argnum], "-nowav"))
  968.        nowav = 1;
  969.      if (!strcmp (argv[argnum], "-fps"))
  970.        show_frame_rate = 1;
  971.  
  972.      if (
  973.         (!strcmp (argv[argnum], "/?")) ||
  974.         (!strcmp (argv[argnum], "?")) ||
  975.         (!strcmp (argv[argnum], "-?")) ||
  976.         (!strcmp (argv[argnum], "help")) ||
  977.         (!strcmp (argv[argnum], "-c")))
  978.        PR_FatalError ("Egerter Software 3Dfx ScreenSaver  v1.0\n"
  979.                       "Copyright 1997 Egerter Software\n\n"
  980.                       "Command Line switches: \n"
  981.                       "/?       - Displays this help screen\n"
  982.                       "-nomusic - Turns off the music\n"
  983.                       "-nowav   - Turns off the 3D jet sounds\n"
  984.                       "-fps     - Display the frame rate\n", "Egerter Software 3Dfx ScreenSaver");
  985.  
  986.      argnum++;
  987.     }
  988.  
  989.   if (nomusic & nowav)
  990.     nosound = 1;
  991.  
  992.  
  993.   PRGUI_InitPath (argv[0]);
  994.   InitializePowerRender ();
  995.  
  996.   PRGUI_GoUserPath ();
  997.   setlib ("es_saver.pkg");
  998.  
  999.   PRGUI_printf (0, 40, "Loading Jet Scene...");
  1000.   LoadJetScene ();
  1001.   PRGUI_printf (0, 50, "Loading Bump Scene...");
  1002.   LoadBumpScene ();
  1003.   PRGUI_printf (0, 60, "Loading Logo Scene...");
  1004.   LoadLogoScene ();
  1005.  
  1006.   if (!nosound)
  1007.     {
  1008.      PRGUI_printf (0, 70, "Initializing Audio...");
  1009.      InitializeAudio ();
  1010.     }
  1011.  
  1012.   do {
  1013.     InitializeWAV ();
  1014.     JetLoop ();
  1015.     FreeWAV ();
  1016.  
  1017.     if (!quit_saver)
  1018.       BumpLoop ();
  1019.  
  1020.     if (!quit_saver)
  1021.       LogoLoop ();
  1022.   } while (!quit_saver);
  1023.  
  1024.   uninstallkbd ();
  1025.   wstoptimer ();
  1026.   wdonetimer ();
  1027.  
  1028.   if (!nomusic)
  1029.     PRSND_StopSong ();
  1030.   FreeWAV ();
  1031.  
  1032.   if (!nosound)
  1033.     {
  1034.      PRSND_CloseVoices ();
  1035.      PRSND_DeleteAllSounds ();
  1036.      PRSND_CloseAudio ();
  1037.     }
  1038.  
  1039. #if !defined (MSGLIDE) && !defined (WTGLIDE)
  1040.   wsetmode (3);
  1041. #endif
  1042. }
  1043.  
  1044.  
  1045.  
  1046.  
  1047.